/**
 * File: AbstractFactory.java
 * Created by: mhaimel
 * Created on: 10 Aug 2009
 * CVS:  $Id: AbstractFactory.java,v 1.2 2009/10/09 15:16:53 mhaimel Exp $
 */
package uk.ac.ebi.curtain.util.file.impl;

import java.io.Closeable;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import uk.ac.ebi.curtain.util.file.impl.FileAccessPool.ChannelType;
import uk.ac.ebi.curtain.utils.io.impl.FileIO;


/**
 * @author mhaimel
 *
 */
public abstract class AbstractFactory implements ChannelFactory {
	private final Log log = LogFactory.getLog(this.getClass());

	/**
	 * {@inheritDoc}
	 */
	public abstract ChannelType getType();
	
	/**
	 * {@inheritDoc}
	 */
	public void activateObject(Object fin, Object cin) throws Exception {
		_doActivateObject(getInfo(fin), getChannelWrapper(cin));
	}

	protected abstract void _doActivateObject(FilePoolInfo info, ChannelWrapper cin) throws Exception;

	/**
	 * {@inheritDoc}
	 */
	public void destroyObject(Object fin, Object cin) throws Exception {
		_doDestroyObject(getInfo(fin), getChannelWrapper(cin));
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void passivateObject(Object fin, Object cin) throws Exception {
		_doPassivateObject(getInfo(fin), getChannelWrapper(cin));
	}

	protected abstract void _doPassivateObject(FilePoolInfo info, ChannelWrapper cin) throws Exception;

	/**
	 * {@inheritDoc}
	 */
	public Object makeObject(Object fin) throws Exception{
		ChannelWrapper wrapper = new ChannelWrapper();
		FilePoolInfo info = getInfo(fin);
		_openChannel(info,wrapper);
		if(getLog().isTraceEnabled()){
			getLog().trace("Create Channel " + info + " using " + this + " --> " + wrapper);
		}
		return wrapper;
	}
	
	protected abstract void _openChannel(FilePoolInfo info, ChannelWrapper wrapper) throws Exception;

	protected void _doDestroyObject(FilePoolInfo info, ChannelWrapper cin) throws Exception{
		_closeChannel(info,cin);
	}
	
	protected void _closeChannel(FilePoolInfo info, ChannelWrapper cin){
		if(getLog().isTraceEnabled()){
			getLog().trace("Close Channel " + info + " using " + this + " --> " + cin);
		}
		Closeable in = cin.getChannel();
		FileIO.closeQuietly(in);
		cin.setChannel(null);
	}

	protected Log getLog() {
		return log;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean validateObject(Object fin, Object cin) {
		return true;
	}
	
	protected ChannelWrapper getChannelWrapper(Object cin){
		return (ChannelWrapper) cin;
	}

	protected FilePoolInfo getInfo(Object fin){
		return (FilePoolInfo) fin;
	}
}
